package com.laxcen.basiclib.core.weex;

import android.app.Activity;
import android.app.Application;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import com.laxcen.basiclib.core.bridgewebview.bean.PushLog;
import com.laxcen.basiclib.core.crashpush.CrashPushManager;
import com.laxcen.basiclib.core.weex.adapter.ImageAdapter;
import com.laxcen.basiclib.core.weex.extend.WXEventModule;
import com.laxcen.basiclib.core.weex.util.AppConfig;
import com.laxcen.basiclib.core.weex.util.CommonUtils;
import com.taobao.weex.IWXRenderListener;
import com.taobao.weex.InitConfig;
import com.taobao.weex.WXSDKEngine;
import com.taobao.weex.WXSDKInstance;
import com.taobao.weex.common.WXException;
import com.taobao.weex.common.WXRenderStrategy;

import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;

import io.sentry.SentryLevel;

/**
 * weex 功能封装
 */
public class WeexManager {
    private volatile static WeexManager weexManager;
    protected ViewGroup mContainer;
    public final ViewGroup getContainer() {
        return mContainer;
    }
    public final void setContainer(ViewGroup container) {
        mContainer = container;
    }
    public static WeexManager getInstance(){
        if(weexManager==null){
            synchronized (WeexManager.class){
                if(weexManager==null){
                    weexManager = new WeexManager();
                }
            }
        }
        return weexManager;
    }
    //在Application里初始化
    public void init(Application application){
        WXSDKEngine.addCustomOptions("appName", "WXSample");
        WXSDKEngine.addCustomOptions("appGroup", "WXApp");
        WXSDKEngine.initialize(application,
                new InitConfig.Builder().setImgAdapter(new ImageAdapter()).build()
        );
        try {
            WXSDKEngine.registerModule("event", WXEventModule.class);
        } catch (WXException e) {
            e.printStackTrace();
        }
        AppConfig.init(application);
    }

    private static final String TAG = "AbsWeexActivity";
    private WXSDKInstance wxsdkInstance;
    protected BroadcastReceiver mBroadcastReceiver;
    public Uri mUri;
    private WxReloadListener mReloadListener;
    private WxRefreshListener mRefreshListener;
    private String mUrl;
    private String mPageName = TAG;
    private WeakReference<Activity> mActivity;
    /**
     * 加载页面
     * @param activity
     */
    public void load(Activity activity){
        mActivity =  new WeakReference<>(activity);
        wxsdkInstance = new WXSDKInstance(activity);
        createWeexInstance();
        wxsdkInstance.onActivityCreate();
        //注册广播
        registerBroadcastReceiver(mBroadcastReceiver, null);
    }

    /**
     * 销毁weex引擎
     */
    protected void destoryWeexInstance() {
        if (wxsdkInstance != null) {
            wxsdkInstance.registerRenderListener(null);
            wxsdkInstance.destroy();
            wxsdkInstance = null;
        }
    }

    /**
     * 创建weex引擎
     */
    public void createWeexInstance() {
        if(mActivity!=null) {
            destoryWeexInstance();
            wxsdkInstance = new WXSDKInstance(mActivity.get());
            wxsdkInstance.registerRenderListener(new IWXRenderListener() {
                @Override
                public void onViewCreated(WXSDKInstance instance, View view) {
                    if (mContainer != null) {
                        mContainer.removeAllViews();
                        mContainer.addView(view);
                    }
                }

                @Override
                public void onRenderSuccess(WXSDKInstance instance, int width, int height) {
                    //载入成功
                }

                @Override
                public void onRefreshSuccess(WXSDKInstance instance, int width, int height) {
                    //刷新成功
                }

                @Override
                public void onException(WXSDKInstance instance, String errCode, String msg) {
                    //报错采集
                    PushLog pushLog = new PushLog();
                    pushLog.setType("weex");
                    pushLog.setLevel(SentryLevel.ERROR);
                    pushLog.setBlankInterface(true);
                    pushLog.setMessage(msg);
                    CrashPushManager.getInstance().pushLog(pushLog);
                }
            });
        }
    }


    /**
     * 重载接口
     */
    public interface WxReloadListener {
        void onReload();
    }

    /**
     * 刷新接口
     */
    public interface WxRefreshListener {
        void onRefresh();
    }


    /**
     * 唤醒
     */
    public void onResume(){
        if (wxsdkInstance != null) {
            wxsdkInstance.onActivityResume();
        }
    }

    /**
     * 挂起
     */
    public void onPause(){
        if (wxsdkInstance != null) {
            wxsdkInstance.onActivityPause();
        }
    }

    /**
     * 停止
     */
    public void onStop(){
        if (wxsdkInstance != null) {
            wxsdkInstance.onActivityStop();
        }
    }

    /**
     * 销毁
     */
    public void onDestroy(){
        if (wxsdkInstance != null) {
            wxsdkInstance.onActivityDestroy();
            wxsdkInstance = null;
        }
        if(mActivity!=null){
            mActivity.clear();
            mActivity = null;
            System.gc();
        }
        unregisterBroadcastReceiver();
    }

    /**
     * 权限回调
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if (wxsdkInstance != null) {
            wxsdkInstance.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    /**
     * 检查是否有权限
     * @param requestCode
     * @param permission
     * @param runnable
     */
    public void runWithPermissionsCheck(int requestCode, String permission, Runnable runnable) {
        checkIsNull();
        if (ContextCompat.checkSelfPermission(mActivity.get(), permission) != PackageManager.PERMISSION_GRANTED) {
            if (ActivityCompat.shouldShowRequestPermissionRationale(mActivity.get(), permission)) {
                Toast.makeText(mActivity.get(), "请授权访问该功能!", Toast.LENGTH_SHORT).show();
            } else {
                ActivityCompat.requestPermissions(mActivity.get(), new String[]{permission}, requestCode);
            }
        } else {
            if (runnable != null) {
                runnable.run();
            }
        }
    }

    /**
     * activity返回
     * @param requestCode
     * @param resultCode
     * @param data
     */
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (wxsdkInstance != null) {
            wxsdkInstance.onActivityResult(requestCode, resultCode, data);
        }
    }

    /**
     * 检查是否有初始化
     */
    private void checkIsNull(){
        if(mActivity==null){
            return;
        }
        if (wxsdkInstance == null) {
           return;
        }
    }
    /**
     * 打开新页面
     * @param url
     */
    protected void renderPageByURL(String url) {
        renderPageByURL(url, null);
    }

    /**
     * 打开页面并携带参数
     * @param url
     * @param jsonInitData
     */
    protected void renderPageByURL(String url, String jsonInitData) {
        checkIsNull();
        CommonUtils.throwIfNull(mContainer, new RuntimeException("Can't render page, container is null"));
        Map<String, Object> options = new HashMap<>();
        options.put(WXSDKInstance.BUNDLE_URL, url);
        wxsdkInstance.renderByUrl(
                mPageName,
                url,
                options,
                jsonInitData,
                CommonUtils.getDisplayWidth(mActivity.get()),
                CommonUtils.getDisplayHeight(mActivity.get()),
                WXRenderStrategy.APPEND_ASYNC);
    }


    private static final String ACTION_DEBUG_INSTANCE_REFRESH = "ACTION_DEBUG_INSTANCE_REFRESH";

    /**
     * 注册广播
     * @param receiver
     * @param filter
     */
    public void registerBroadcastReceiver(BroadcastReceiver receiver, IntentFilter filter) {
        checkIsNull();
        mBroadcastReceiver = receiver != null ? receiver : new DefaultBroadcastReceiver();
        if (filter == null) {
            filter = new IntentFilter();
        }
        filter.addAction(ACTION_DEBUG_INSTANCE_REFRESH);
        filter.addAction(WXSDKEngine.JS_FRAMEWORK_RELOAD);
        LocalBroadcastManager.getInstance(mActivity.get())
                .registerReceiver(mBroadcastReceiver, filter);
        if (mReloadListener == null) {
            setReloadListener(new WxReloadListener() {

                @Override
                public void onReload() {
                    createWeexInstance();
                    renderPage();
                }

            });
        }

        if (mRefreshListener == null) {
            setRefreshListener(new WxRefreshListener() {
                @Override
                public void onRefresh() {
                    createWeexInstance();
                    renderPage();
                }

            });
        }
    }

    /**
     * 销毁广播
     */
    public void unregisterBroadcastReceiver() {
        checkIsNull();
        if (mBroadcastReceiver != null) {
            LocalBroadcastManager.getInstance(mActivity.get())
                    .unregisterReceiver(mBroadcastReceiver);
            mBroadcastReceiver = null;
        }
        setReloadListener(null);
        setRefreshListener(null);
    }

    /**
     * 设置重载监听
     * @param reloadListener
     */
    public void setReloadListener(WxReloadListener reloadListener) {
        mReloadListener = reloadListener;
    }

    /**
     * 设置刷新监听
     * @param refreshListener
     */
    public void setRefreshListener(WxRefreshListener refreshListener) {
        mRefreshListener = refreshListener;
    }

    /**
     * 获取当前url
     * @return
     */
    public String getUrl() {
        return mUrl;
    }


    private void setUrl(String url) {
        mUrl = url;
    }

    /**
     * 加载url
     * @param url
     */
    public void loadUrl(String url) {
        setUrl(url);
        renderPage();
    }

    /**
     * 加载前处理
     */
    protected void preRenderPage() {

    }

    /**
     * 加载后处理
     */
    protected void postRenderPage() {

    }

    /**
     * 重载页面
     */
    public void renderPage() {
        preRenderPage();
        renderPageByURL(mUrl);
        postRenderPage();
    }

    /**
     * 是否是本地页面
     * @return
     */
    protected boolean isLocalPage() {
        boolean isLocalPage = true;
        if (mUri != null) {
            String scheme = mUri.getScheme();
            isLocalPage = !mUri.isHierarchical() ||
                    (!TextUtils.equals(scheme, "http") && !TextUtils.equals(scheme, "https"));
        }
        return isLocalPage;
    }

    /**
     * 接收关闭事件
     */
    public class DefaultBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (ACTION_DEBUG_INSTANCE_REFRESH.equals(intent.getAction())) {
                if (mRefreshListener != null) {
                    mRefreshListener.onRefresh();
                }
            } else if (WXSDKEngine.JS_FRAMEWORK_RELOAD.equals(intent.getAction())) {
                if (mReloadListener != null) {
                    mReloadListener.onReload();
                }
            }
        }
    }
}
